Monas demo code
masa氏がいくつかmainに上げてくれたYudai.icon
code: main.py
import json, pickle
from fastapi import FastAPI
from cryptography.fernet import Fernet
from fakeIPFS import FakeIPFS
from cache import CryptreeCache
from cryptree import CryptTreeNode, PlainNode
from model import RootRequest, UploadDataRequest
app = FastAPI()
fake_ipfs = FakeIPFS()
cryptree_cache = CryptreeCache()
current_node = None
# ファイルシステムのルート作成
@app.post("/signup")
def create_root():
# DID等は、一旦スキップ、TODO
root = CryptTreeNode(name="root", isDirectory=True, parent=None)
data = {
"key":root.keydata,
"metadata":root.get_encrypted_metadata()
}
root_cid = fake_ipfs.add(json.dumps(data).encode()) # ルートのIPFS置き場所はどっかに覚えとおかないといけない希ガス, フロント?バッグ?
return root_cid, root.subfolder_key # ルート情報を復号化する鍵もどっかに覚えとおかないといけない希ガス, フロント?バッグ?
# ファイルシステムのルート取得, ルートの情報があるIPFSのCIDと鍵を渡してもらう想定
@app.post("/login")
def fetch_root(req: RootRequest):
encrypted_data = json.loads(fake_ipfs.cat(req.cid).decode())
key_info = encrypted_data"key" # Derive key
sk = req.root_key
# Derive metadata
decrypted_data = Fernet(dk).decrypt(encrypted_data"metadata") # Set root info and cache
global current_node
current_node = PlainNode(json.loads(decrypted_data.decode()), req.root_key)
cryptree_cache.put("#", current_node)
return decrypted_data
@app.get("/{path}")
def read(path: str):
global current_node
if current_node is None:
return "You should login"
if cryptree_cache.contains_key(path):
current_node = cryptree_cache.get(path)
return current_node.metadata
print(current_node.metadata)
if path not in current_node.metadata"child": return "No data"
encrypted_data = json.loads(fake_ipfs.cat(cid).decode())
key_info = encrypted_data"key" decrypted_data = Fernet(dk).decrypt(encrypted_data"metadata") current_node.metadata = json.loads(decrypted_data.decode())
current_node.subfolder_key = sk
cryptree_cache.put(path, current_node)
return decrypted_data
# 新規フォルダー・ファイル作成
# TODO recursion
@app.post("/upload")
def upload_data(req: UploadDataRequest):
global current_node
if current_node is None:
return "You should login"
new_node = None
if req.isDirectory:
new_node = CryptTreeNode(name=req.name, isDirectory=True, parent=current_node)
else:
new_node = CryptTreeNode(name=req.name, isDirectory=False, parent=current_node, data=req.data)
data = {
"key":new_node.keydata,
"metadata":new_node.get_encrypted_metadata()
}
print(data)
cid = fake_ipfs.add(json.dumps(data).encode())
current_node.add_node(cid, req.name, req.path, req.isDirectory)
# TODO recursion
# path = req.path.split("/")
# while len(path) != 0:
# node.get_encrypted_metadata()
# fake_ipfs.add(json.dumps(data).encode())
return current_node.metadata
# 再暗号化
@app.post("/reencrypt")
def reencrypt():
pass # TODO
# Share data
@app.get("/share")
def get_key_for_sharing_data():
pass # TODO
# 以下、まだ使ってないです。無視してください、すみません、消したくないです、PAGNI
def serialize_object(obj) -> bytes:
return pickle.dumps(obj)
def deserialize_object(data: bytes):
return pickle.loads(data)
Fast APIについて見たけどちゃんと理解していないYudai.icon
code:metadata.json
{
"name": "Folder1",
"owner": "0x...123",
"creation_date": "2023-09-09",
"location": "folder1_uri",
"parent": { "name": "parent.name", "location": "parent.location" },
"child": [
{ "name": "File1", "isFile": true, "creation_date": "2023-09-09", "location": "file1.location" },
{ "name": "File2", "isFile": true, "creation_date": "2023-09-09", "location": "file2.location" },
{ "name": "Folder2", "isFile": false, "creation_date": "2023-09-09", "location": "folder2.location" }
]
}
mameta.iconからメタデータの状態を送ってもらった
igmaに合わせてmetadata変更しました。
・owner 追加
・childにcreation_date追加(本来はmodifyですが一旦createで置いてます。)
ownerが必要ないかどうか?
僕的にはcryptreeのtreeの状態自体を共有相手に渡すわけではない(CIDと鍵)から、Owner情報はメタデータ上に必要だと思うYudai.icon 相手側に表示されるためにYudai.icon
それとメタデータを見ていると思うがparentのメタデータにchaildを入れる必要があるから、メタデータに追加する度に更新されて再暗号化しないといけなくない?
IPNSで確かにこれは解決できるとは思うんだけど、現在最新の状態のCIDをIPNSに紐づける必要がある